home *** CD-ROM | disk | FTP | other *** search
- /************************************************************************/
- /* */
- /* The file functions. */
- /* These functions handle one read-file and one write-file. */
- /* */
- /************************************************************************/
-
- #include <proto/exec.h>
- #include <proto/dos.h>
-
- /* SAS/C V5.10b is broken, so we can't include clib/alib_protos.h */
- void NewList(struct List *);
-
- #include <string.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <ctype.h>
- #include <stdarg.h>
- #include <errno.h>
-
- /************************************************************************/
-
- #include "main.h"
- #include "File.h"
-
- /************************************************************************/
-
- char *ReadFilename, *WriteFilename;
-
- static FILE *WriteHandle, *ReadHandle;
- static ULONG ReadLineNo;
- static int ReadColumn;
-
- static struct MinList UnreadList;
-
- /************************************************************************/
- /* */
- /* Return complete filename */
- /* */
- /************************************************************************/
-
- static char *
- GetFilename (int DirNumber, char *Name)
-
- {
- int FilenameLength;
- char *Filename;
- int FirstError;
-
- FirstError=TRUE;
- FilenameLength = 256;
- while (TRUE)
- {
- Filename = xmalloc (FilenameLength);
- NoMemReTry:
- if (NameFromLock (Dirs[CURRENTDIR], Filename, FilenameLength))
- {
- if (DirNumber == CURRENTDIR || AddPart (Filename, Arguments.Dirs[DirNumber], FilenameLength))
- {
- if (AddPart (Filename, Name, FilenameLength))
- {
- return Filename;
- }
- }
- }
- else
- {
- switch(IoErr())
- {
- case ERROR_NO_FREE_STORE:
- {
- if (FirstError)
- {
- errno=ENOMEM;
- perror("Current directory");
- FirstError=FALSE;
- }
- Delay(2*TICKS_PER_SECOND);
- if (!CheckSignal(SIGBREAKF_CTRL_C))
- {
- goto NoMemReTry;
- }
- errno=ERROR_BREAK;
- perror(NULL);
- CloseAll(RETURN_ERROR);
- }
- break;
-
- case ERROR_LINE_TOO_LONG:
- {
- free (Filename);
- FilenameLength += 256;
- }
- break;
-
- default:
- {
- errno=IoErr();
- perror ("Current directory");
- CloseAll (RETURN_ERROR);
- }
- break;
-
- }
- }
- }
- /* not reached */
- }
-
- /************************************************************************/
- /* */
- /* Open a file for reading. */
- /* */
- /************************************************************************/
-
- void
- ROpen (int DirNumber, char *Name)
-
- {
- int FirstError;
-
- ReadFilename = GetFilename (DirNumber, Name);
-
- NewList ((struct List *) &UnreadList);
-
- CurrentDir (Dirs[DirNumber]);
- FirstError=TRUE;
- while (!(ReadHandle = fopen (ReadFilename, "r")))
- {
- if (errno==ENOMEM)
- {
- if (FirstError)
- {
- perror(ReadFilename);
- FirstError=FALSE;
- }
- Delay(2*TICKS_PER_SECOND);
- if (CheckSignal(SIGBREAKF_CTRL_C))
- {
- errno=ERROR_BREAK;
- perror(NULL);
- CloseAll(RETURN_ERROR);
- }
- }
- else
- {
- perror (ReadFilename);
- CloseAll (RETURN_ERROR);
- }
- }
- SetVBuf (fileno(ReadHandle), NULL, BUF_FULL, 16 * 1024);
-
- ReadLineNo = 1;
- ReadColumn = 0;
- }
-
- /************************************************************************/
- /* */
- /* Create a directory tree */
- /* */
- /************************************************************************/
-
- static void
- CreateDirectory (char *Name)
-
- {
- BPTR DirLock;
-
- if (!Name[0])
- {
- return;
- }
-
- if ((DirLock = Lock (Name, SHARED_LOCK)))
- {
- UnLock (DirLock);
- return;
- }
-
- if (IoErr () == ERROR_OBJECT_NOT_FOUND)
- {
- char *t;
-
- t = PathPart (Name);
- if (t != Name)
- {
- char c;
-
- c = *t;
- *t = '\0';
- CreateDirectory (Name);
- *t = c;
- }
- if ((DirLock = CreateDir (Name)))
- {
- UnLock (DirLock);
- return;
- }
- }
- errno=IoErr();
- perror (Name);
- CloseAll (RETURN_ERROR);
- }
-
- /************************************************************************/
- /* */
- /* Open a file for writing. */
- /* */
- /************************************************************************/
-
- void
- WOpen (int DirNumber, char *Name)
-
- {
- WriteFilename = GetFilename (DirNumber, Name);
-
- if (Pass2)
- {
- char *t;
- char c;
- int FirstError;
-
- CurrentDir (Dirs[DirNumber]);
- t = PathPart (WriteFilename);
- c = *t;
- *t = '\0';
- CreateDirectory (WriteFilename);
- *t = c;
- FirstError=TRUE;
- while (!(WriteHandle = fopen (WriteFilename, "w")))
- {
- if (errno==ENOMEM)
- {
- if (FirstError)
- {
- perror(WriteFilename);
- FirstError=FALSE;
- }
- Delay(2*TICKS_PER_SECOND);
- if (CheckSignal(SIGBREAKF_CTRL_C))
- {
- errno=ERROR_BREAK;
- perror(NULL);
- SetRC(RETURN_ERROR);
- break;
- }
- }
- else
- {
- perror (WriteFilename);
- SetRC (RETURN_ERROR);
- break;
- }
- }
- if (WriteHandle)
- {
- SetVBuf (fileno(WriteHandle), NULL, BUF_FULL, 16 * 1024);
- }
- }
- }
-
- /************************************************************************/
- /* */
- /* Close the read-file. */
- /* */
- /************************************************************************/
-
- void
- RClose (void)
-
- {
- if (ReadHandle)
- {
- fclose (ReadHandle);
- ReadHandle = NULL;
- free (ReadFilename);
- }
-
- if (UnreadList.mlh_Head)
- {
- struct Word *Word;
-
- while ((Word = (struct Word *) RemTail ((struct List *) &UnreadList)))
- {
- FreeWord (Word);
- }
- }
- }
-
- /************************************************************************/
- /* */
- /* Close the write-file. */
- /* */
- /************************************************************************/
-
- void
- WClose (void)
-
- {
- if (WriteHandle)
- {
- if (fclose (WriteHandle)==EOF)
- {
- perror (WriteFilename);
- SetRC (RETURN_ERROR);
- }
- SetProtection (WriteFilename, FIBF_EXECUTE);
- WriteHandle = NULL;
- }
- if (WriteFilename)
- {
- free(WriteFilename);
- WriteFilename=NULL;
- }
- }
-
- /************************************************************************/
- /* */
- /* Read a word from the read-file. This is just an internal function. */
- /* */
- /************************************************************************/
-
- struct Word *BasicReadWord (int AllowEOF)
-
- {
- struct Word *NewWord;
-
- if (CheckSignal (SIGBREAKF_CTRL_C))
- {
- errno=ERROR_BREAK;
- perror (NULL);
- CloseAll (RETURN_WARN);
- }
-
- if (!(NewWord = (struct Word *) RemTail ((struct List *) &UnreadList)))
- {
- struct Word Word;
- int StartColumn;
-
- memset (&Word, 0, sizeof (Word));
-
- StartColumn = ReadColumn;
-
- NewWord = NULL;
- while (!NewWord)
- {
- static char *InputBuffer;
- static size_t InputBufferSize;
-
- int c;
-
- Word.Line = ReadLineNo;
-
- c = fgetc (ReadHandle);
- ReadColumn++;
- if (c == '\t')
- {
- /* really +8, but we have already added 1 */
- ReadColumn = (ReadColumn + 7) & ~7;
- }
- else if (isalpha (c) || c == '_')
- {
- Word.Whitespace = ReadColumn - StartColumn - 1;
- while (isalpha (c) || isdigit (c) || c == '_')
- {
- if ((isupper (c) && Word.Length > 0) ||
- isdigit (c) ||
- c == '_')
- {
- Word.Special = TRUE;
- }
- if (Word.Length+1>=InputBufferSize)
- {
- InputBuffer=xrealloc(InputBuffer,InputBufferSize+=128);
- }
- InputBuffer[Word.Length++] = c;
- c = fgetc (ReadHandle);
- ReadColumn++;
- }
- if (ferror (ReadHandle))
- {
- perror (ReadFilename);
- CloseAll (RETURN_ERROR);
- }
- ungetc (c,ReadHandle);
- ReadColumn--;
-
- InputBuffer[Word.Length] = '\0';
- NewWord = xmalloc (sizeof (*NewWord) + Word.Length);
- *NewWord = Word;
- strcpy (NewWord->Word, InputBuffer);
- }
- else if (isdigit(c))
- {
- Word.Whitespace = ReadColumn - StartColumn - 1;
- while (isdigit(c) || c=='x')
- {
- if (Word.Length+1>=InputBufferSize)
- {
- InputBuffer=xrealloc(InputBuffer,InputBufferSize+=128);
- }
- InputBuffer[Word.Length++]=c;
- c=fgetc(ReadHandle);
- ReadColumn++;
- }
- if (ferror(ReadHandle))
- {
- perror(ReadFilename);
- CloseAll(RETURN_ERROR);
- }
- ungetc(c,ReadHandle);
- ReadColumn--;
-
- InputBuffer[Word.Length] = '\0';
- NewWord = xmalloc (sizeof (*NewWord) + Word.Length);
- *NewWord = Word;
- strcpy (NewWord->Word, InputBuffer);
- }
- else if (c == '\n')
- {
- Word.Newline++;
- StartColumn = 0;
- ReadColumn = 0;
- ReadLineNo++;
- }
- else if (c == EOF)
- {
- if (ferror(ReadHandle))
- {
- perror (ReadFilename);
- CloseAll (RETURN_ERROR);
- }
- if (!AllowEOF)
- {
- fprintf (stderr, "%s: unexpected end of file\n", ReadFilename);
- CloseAll (RETURN_ERROR);
- }
- NewWord = xmalloc (sizeof (*NewWord));
- *NewWord = Word;
- NewWord->Word[0] = '\0';
- NewWord->Whitespace = 0;
- NewWord->Newline = (NewWord->Newline > 0);
- NewWord->Special=TRUE;
- }
- else if (c != ' ')
- {
- if (c == 0x0c)
- {
- ReadColumn = 0;
- Word.Whitespace = 0;
- }
- else
- {
- Word.Whitespace = ReadColumn - StartColumn - 1;
- }
- NewWord = xmalloc (sizeof (*NewWord) + 1);
- *NewWord = Word;
- NewWord->Word[0] = c;
- NewWord->Word[1] = '\0';
- NewWord->Length = 1;
- NewWord->Special = TRUE;
- }
- }
- }
- return NewWord;
- }
-
-
- /************************************************************************/
- /* */
- /* Concat several words to one. */
- /* Intervening whitespace and newlines are ignored. */
- /* The individual words are freed. */
- /* */
- /************************************************************************/
-
- static struct Word *ConcatWords(struct Word *FirstWord, ...)
-
- {
- struct Word **CurrentWord;
- struct Word *NewWord;
- size_t NewLength;
- char *t;
-
- NewLength=0;
- for (CurrentWord=&FirstWord; *CurrentWord; CurrentWord++)
- {
- NewLength+=(*CurrentWord)->Length;
- }
-
- NewWord=xmalloc(sizeof(*NewWord)+NewLength);
- NewWord->Line=FirstWord->Line;
- NewWord->Whitespace=FirstWord->Whitespace;
- NewWord->Newline=FirstWord->Newline;
- NewWord->Special=TRUE;
- NewWord->Length=NewLength;
-
- t=NewWord->Word;
- for (CurrentWord=&FirstWord; *CurrentWord; CurrentWord++)
- {
- t=stpcpy(t,(*CurrentWord)->Word);
- FreeWord(*CurrentWord);
- }
-
- return NewWord;
- }
-
- /************************************************************************/
- /* */
- /* Read a word. This is the real function that will handle all known */
- /* exceptions to the normal word definition. */
- /* */
- /************************************************************************/
-
- struct Word *ReadWord(int AllowEOF)
-
- {
- struct Word *Word;
- struct Word *NextWord;
-
- Word=BasicReadWord(AllowEOF);
- NextWord=BasicReadWord(TRUE);
-
- /* 8svx */
- if (!strcmp(Word->Word,"8"))
- {
- if (!NextWord->Whitespace && !NextWord->Newline && !strcasecmp(NextWord->Word,"svx"))
- {
- Word=ConcatWords(Word,NextWord,NULL);
- NextWord=BasicReadWord(TRUE);
- }
- }
-
- /* -handler */
- if (!NextWord->Whitespace && !NextWord->Newline && !strcmp(NextWord->Word,"-"))
- {
- struct Word *NextNextWord;
-
- NextNextWord=BasicReadWord(TRUE);
- if (!NextNextWord->Whitespace && !NextNextWord->Newline && !strcasecmp(NextNextWord->Word,"handler"))
- {
- Word=ConcatWords(Word,NextWord,NextNextWord,NULL);
- NextWord=BasicReadWord(TRUE);
- }
- else
- {
- UnreadWord(NextNextWord);
- }
- }
-
- /* .irgendwas */
- if (!NextWord->Whitespace && !NextWord->Newline && !strcmp(NextWord->Word,"."))
- {
- struct Word *NextNextWord;
-
- NextNextWord=BasicReadWord(TRUE);
- if (!NextNextWord->Whitespace && !NextNextWord->Newline && !NextNextWord->Special)
- {
- Word=ConcatWords(Word,NextWord,NextNextWord,NULL);
- NextWord=BasicReadWord(TRUE);
- }
- else
- {
- UnreadWord(NextNextWord);
- }
- }
- UnreadWord(NextWord);
- return Word;
- }
-
- /************************************************************************/
- /* */
- /* Unread a word back to the read-file */
- /* */
- /************************************************************************/
-
- void UnreadWord (struct Word *Word)
-
- {
- AddTail ((struct List *) &UnreadList, (struct Node *) &Word->Node);
- }
-
- #ifndef FreeWord
- /************************************************************************/
- /* */
- /* Free a read word */
- /* */
- /************************************************************************/
-
- void FreeWord (struct Word *Word)
-
- {
- free (Word);
- }
- #endif
-
- /************************************************************************/
- /* */
- /* Read until a terminating word */
- /* The terminator is unread */
- /* */
- /************************************************************************/
-
- char *
- ReadUntil (char *Terminator)
-
- {
- struct MinList WordList;
- struct Word *Word;
- size_t Length;
- char *Text, *t;
-
- NewList ((struct List *) &WordList);
- Length = 1;
- Word = ReadWord (FALSE);
- while (strcmp (Word->Word, Terminator))
- {
- AddTail ((struct List *) &WordList, (struct Node *) Word);
- Length += Word->Length + Word->Whitespace;
- Word = ReadWord (FALSE);
- }
- UnreadWord (Word);
- t = Text = xmalloc (Length);
- while ((Word = (struct Word *) RemHead ((struct List *) &WordList)))
- {
- while (Word->Whitespace)
- {
- *(t++) = ' ';
- Word->Whitespace--;
- }
- t = stpcpy (t, Word->Word);
- FreeWord (Word);
- }
- return Text;
- }
-
- /************************************************************************/
- /* */
- /* Write a formatted string to the write-file */
- /* */
- /************************************************************************/
-
- void
- WPrintf (char *FormatString,...)
-
- {
- if (WriteHandle)
- {
- va_list ParamList;
-
- va_start(ParamList,FormatString);
- if (vfprintf (WriteHandle, FormatString, ParamList) == EOF)
- {
- va_end(ParamList);
- perror (WriteFilename);
- CloseAll (RETURN_ERROR);
- }
- va_end(ParamList);
- }
- }
-
- /************************************************************************/
- /* */
- /* Write the header for an AmigaGuide file */
- /* */
- /************************************************************************/
-
- void
- WriteHeader (char *Database, char *Master)
-
- {
- if (Pass2)
- {
- struct DateTime DateTime;
- char StrDate[LEN_DATSTRING], StrTime[LEN_DATSTRING];
-
- DateStamp (&DateTime.dat_Stamp);
- DateTime.dat_Format = FORMAT_DOS;
- DateTime.dat_Flags = 0;
- DateTime.dat_StrDay = NULL;
- DateTime.dat_StrDate = StrDate;
- DateTime.dat_StrTime = StrTime;
-
- DateToStr (&DateTime);
-
- WPrintf ("@DATABASE \x22%s\x22\n", Database);
- if (Master)
- WPrintf ("@MASTER \x22%s\x22\n", Master);
- WPrintf ("@REMARK This file was created by " PROGRAM_NAME " " PROGRAM_VERSION " on %s %s\n"
- "@REMARK Do not edit\n"
- "@REMARK ADtoHT is " PROGRAM_COPYRIGHT "\n",
- StrDate, StrTime);
- }
- }
-
- /************************************************************************/
- /* */
- /* Write a words white-space to the write-file */
- /* */
- /************************************************************************/
-
- void
- WriteWhitespace (struct Word *Word)
-
- {
- while (Word->Newline)
- {
- WPrintf ("\n");
- Word->Newline--;
- }
- while (Word->Whitespace)
- {
- WPrintf (" ");
- Word->Whitespace--;
- }
- }
-
- /************************************************************************/
- /* */
- /* Write a word to the write-file */
- /* */
- /************************************************************************/
-
- void
- WriteWord (struct Word *Word)
-
- {
- WriteWhitespace (Word);
- if (Word->Length == 1)
- {
- switch (Word->Word[0])
- {
- case '\\':
- WPrintf ("\\\\");
- return;
- case '@':
- WPrintf ("@@");
- return;
- }
- }
- WPrintf ("%s", Word->Word);
- }
-
- /************************************************************************/
- /* */
- /* Skip Read-File until 0x0c is found */
- /* Returns the last char read (may be -1 == EOF) */
- /* */
- /************************************************************************/
-
- long
- ReadSkip (void)
-
- {
- long c;
- struct Word *Word;
-
- while ((Word=(struct Word *)RemTail((struct List *)&UnreadList)))
- {
- if (Word->Word[0]==0x0c)
- {
- return (long)Word->Word[0];
- }
- if (!Word->Word[0])
- {
- return -1;
- }
- FreeWord(Word);
- }
-
- do
- {
- c = fgetc (ReadHandle);
- }
- while (c != 0x0c && c != EOF);
-
- return c;
- }
-
- /************************************************************************/
- /* */
- /* Output a bold, centered headline */
- /* */
- /************************************************************************/
-
- void
- WHeadline (char *Text)
-
- {
- int i;
-
- for (i = (*Arguments.Width - strlen (Text) - (*Arguments.Version >= 39)) / 2; i; i--)
- {
- WPrintf (" ");
- }
- WPrintf (*Arguments.Version >= 39 ? "@{b}%s@{ub}\n" : "%s\n", Text);
- }
-